package jehc.djshi.job.publisher;

import cn.hutool.core.collection.CollectionUtil;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import jehc.djshi.job.vo.ChannelEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 通道管理缓存中心
 *
 */
@Component
@Slf4j
@Lazy
public class ChannelUtil {

    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);//通道组

    private static Map<String,ChannelEntity> channelConcurrentHashMap = new ConcurrentHashMap<>();//通道号维护（与channelEntityConcurrentHashMap做转换）

    private static Map<String,List<ChannelEntity>> channelEntityConcurrentHashMap = new ConcurrentHashMap<>();//通道维护缓存（一个组中）,key为clientGroupId

    /**
     * 存放
     * @param key
     * @param channelEntity
     * @return
     */
    public boolean putChannel(String key,ChannelEntity channelEntity){
        boolean result = true;
        try {
            if(CollectionUtil.isEmpty(channelConcurrentHashMap)){
                channelConcurrentHashMap = new ConcurrentHashMap<>();
            }
            channelConcurrentHashMap.put(key,channelEntity);
        }catch (Exception e){
            log.error("存放Channel出现异常：",e);
            result = false;
        }
        return result;
    }

    /**
     * 获取
     * @param key
     * @return
     */
    public ChannelEntity getChannel(String key){
        if(CollectionUtil.isEmpty(channelConcurrentHashMap)){
            return null;
        }
        try {
            if(CollectionUtil.isEmpty(channelConcurrentHashMap)){
                channelConcurrentHashMap = new ConcurrentHashMap<>();
            }
            ChannelEntity channelEntity = channelConcurrentHashMap.get(key);
            return channelEntity;
        }catch (Exception e){
            log.error("获取Channel出现异常：",e);
        }
        return null;
    }

    /**
     *  根据ChannelId移除
     * @param key
     * @return
     */
    public boolean removeChannel(String key){
        boolean result = true;
        try {
            channelConcurrentHashMap.remove(key);
        }catch (Exception e){
            log.error("移除通道出现异常：",e);
            result = false;
        }
        return result;
    }


    /**
     * 存放
     * @param key
     * @param channelEntity
     * @return
     */
    public boolean put(String key,ChannelEntity channelEntity){
        boolean result = true;
        try {
            if(CollectionUtil.isEmpty(channelEntityConcurrentHashMap)){
                channelEntityConcurrentHashMap = new ConcurrentHashMap<>();
            }
            List<ChannelEntity> channelEntities = channelEntityConcurrentHashMap.get(key);
            if(CollectionUtil.isEmpty(channelEntities)){
                List<ChannelEntity> list = new ArrayList<>();
                list.add(channelEntity);
                channelEntityConcurrentHashMap.put(key,list);
            }else{
                //查找是否已经存在 如果存在则需要移除重新添加（原因可能通道已经销毁）
                Iterator<ChannelEntity> iterator = channelEntities.iterator();
                while (iterator.hasNext()){
                    ChannelEntity entity = iterator.next();
                    if(entity.getClientId().equals(channelEntity.getClientId())){
                        iterator.remove();
                    }
                }
                channelEntities.add(channelEntity);//重新添加
                channelEntityConcurrentHashMap.put(key,channelEntities);
            }

        }catch (Exception e){
            log.error("存放通道出现异常：",e);
            result = false;
        }
        return result;
    }

    /**
     * 获取
     * @param key
     * @return
     */
    public List<ChannelEntity> get(String key){
        if(CollectionUtil.isEmpty(channelEntityConcurrentHashMap)){
            return null;
        }
        try {
            if(CollectionUtil.isEmpty(channelEntityConcurrentHashMap)){
                channelEntityConcurrentHashMap = new ConcurrentHashMap<>();
            }
            List<ChannelEntity> channelEntities = channelEntityConcurrentHashMap.get(key);
            return channelEntities;
        }catch (Exception e){
            log.error("获取通道出现异常：",e);
        }
        return null;
    }

    /**
     *  根据组移除
     * @param key
     * @return
     */
    public boolean remove(String key){
        boolean result = true;
        try {
            channelEntityConcurrentHashMap.remove(key);
        }catch (Exception e){
            log.error("移除通道出现异常：",e);
            result = false;
        }
        return result;
    }

    /**
     * 根据clientId移除
     * @param clientGroupId
     * @param clientId
     * @return
     */
    public boolean remove(String clientGroupId,String clientId){
        boolean result = true;
        try {
            List<ChannelEntity> channelEntities = get(clientGroupId);
            if(CollectionUtil.isEmpty(channelEntities)){
                return result;
            }
            Iterator<ChannelEntity> iterator = channelEntities.iterator();
            while (iterator.hasNext()){
                ChannelEntity entity = iterator.next();
                if(entity.getClientId().equals(clientId)){
                    iterator.remove();
                }
            }
            //空集合则移除map
            if(CollectionUtil.isEmpty(channelEntities)){
                channelEntityConcurrentHashMap.remove(clientGroupId);
            }
        }catch (Exception e){
            log.error("移除通道出现异常：",e);
            result = false;
        }
        return result;
    }


    /**
     * 添加通道到组中
     * @param channel
     * @return
     */
    public boolean add(Channel channel){
        boolean result = true;
        try {
            channelGroup.add(channel);
        }catch (Exception e){
            log.error("添加通道到组中失败！",e);
            result = false;
        }
        return result;
    }

    /**
     * 删除通道到组中通道
     * @param channel
     * @return
     */
    public boolean delete(Channel channel){
        boolean result = true;
        try {
            channelGroup.remove(channel);
        }catch (Exception e){
            log.error("删除通道到组中通道失败！",e);
            result = false;
        }
        return result;
    }
}
